Skip to content

feat: implement X OAuth 2.0 PKCE backend and env var support#60

Open
shaal wants to merge 1 commit intoviperrcrypto:mainfrom
shaal:feat/x-oauth-backend
Open

feat: implement X OAuth 2.0 PKCE backend and env var support#60
shaal wants to merge 1 commit intoviperrcrypto:mainfrom
shaal:feat/x-oauth-backend

Conversation

@shaal
Copy link

@shaal shaal commented Mar 24, 2026

Summary

  • Implements the complete X OAuth 2.0 PKCE flow backend that the existing Live Import UI expects but was missing
  • Adds environment variable support (X_OAUTH_CLIENT_ID, X_OAUTH_CLIENT_SECRET) as fallback for X OAuth credentials, consistent with how ANTHROPIC_API_KEY works
  • Adds env var documentation to .env.example

New API routes

Route Method Description
/api/import/x-oauth/status GET Returns OAuth config & connection status
/api/import/x-oauth/authorize GET Generates PKCE challenge and returns X auth URL
/api/import/x-oauth/callback GET Handles X redirect, exchanges code for tokens
/api/import/x-oauth/disconnect POST Revokes token and clears stored credentials
/api/import/x-oauth/fetch POST Fetches bookmarks via X API v2 with pagination

Note

The X API v2 GET /2/users/:id/bookmarks endpoint requires a paid developer plan (Basic at $200/month). Free-tier accounts will see a credits error after connecting. This is an X platform limitation, not a Siftly bug — but it may be worth adding a note in the UI.

Test plan

  • Set X_OAUTH_CLIENT_ID and X_OAUTH_CLIENT_SECRET in .env.local
  • Verify /import page shows "Connect X Account" button (not "not configured" warning)
  • Click connect → redirects to X authorization page
  • After authorizing, callback redirects back to /import?x_connected=true
  • Status endpoint shows connected: true with user info
  • Disconnect clears tokens and reverts to "Connect" button

Closes #59

- Add complete OAuth 2.0 PKCE flow: authorize, callback, status,
  disconnect, and bookmark fetch endpoints
- Support X_OAUTH_CLIENT_ID and X_OAUTH_CLIENT_SECRET env vars
  as fallback when credentials aren't stored in the database
- Auto-refresh expired tokens using offline.access scope
- Paginate through X API v2 bookmarks with media expansion
- Document new env vars in .env.example

Closes viperrcrypto#59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Live import (X OAuth 2.0 PKCE) requires paid API tier for bookmarks

1 participant